package com.acme.bankapp.service.bank;

import com.acme.bankapp.domain.bank.*;
import com.acme.bankapp.domain.exceptions.ClientExistsException;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

public class BankDataLoaderService {
    public static List<Client> getClients(File file) {
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            List<Client> clientList = new ArrayList<>();
            String line;
            while ((line = br.readLine()) != null) {
                clientList.add(parseLine(line));
            }
            return clientList;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Client parseLine(String line) {
        StringTokenizer st = new StringTokenizer(line, ";");
        boolean isCheckingAccount = true;
        double balance = 0;
        double overdraft = 0;
        String name = "noname";
        Gender gender = Gender.MALE;
        String[] fields;
        while (st.hasMoreTokens()) {
            fields = st.nextToken().split("=");
            switch (fields[0]) {
                case "accounttype":
                    if ("s".equals(fields[1])) {
                        isCheckingAccount = false;
                    }
                    break;
                case "balance":
                    balance = Double.parseDouble(fields[1]);
                    break;
                case "overdraft":
                    overdraft = Double.parseDouble(fields[1]);
                    break;
                case "name":
                    name = fields[1];
                    break;
                case "gender":
                    if ("f".equals(fields[1])) {
                        gender = Gender.FEMALE;
                    }
                    break;
            }
        }
        if (isCheckingAccount) {
            return new Client(new CheckingAccount(balance, overdraft), name, gender);
        } else {
            return new Client(new SavingsAccount(balance), name, gender);
        }
    }

    public static Bank readBank(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        return (Bank) ois.readObject();
    }

    public static void saveBank(Bank bank) {
        try (
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("C:/Users/Public/temp/bank.ser"))
        ) {
            objectOutputStream.writeObject(bank);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Bank createBankByParams(HashMap<String, ArrayList<String>> listOfArguments) {
        Bank bank = null;
        if (listOfArguments.get("-loadbank") != null) {
            try (
                    ObjectInputStream objectInputStream =
                            new ObjectInputStream(new FileInputStream(listOfArguments.get("-loadbank").get(0)))
            ) {
                bank = readBank(objectInputStream);
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        if (bank == null) {
            bank = new Bank();
        }
        if (listOfArguments.get("-loadfeed") != null) {
            for (String filePath : listOfArguments.get("-loadfeed")) {
                List<Client> clients = getClients(new File(filePath));
                for (Client client : clients) {
                    try {
                        BankService.addClient(bank, client);
                    } catch (ClientExistsException e) {
                        System.err.println(e.getMessage());
                    }
                }
            }
        }
        return bank;
    }
}
